#include <sys/socket.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char** argv)
{
	struct sockaddr_in seraddr;
	int sfd;

	memset(&seraddr, 0, sizeof(seraddr));
	seraddr.sin_family = AF_INET;
	seraddr.sin_port = htons(7777);
	seraddr.sin_addr.s_addr = htonl(INADDR_ANY);

	sfd = socket(AF_INET, SOCK_STREAM, 0);

	int opt = 1;

	setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

	bind(sfd, (struct sockaddr*)&seraddr, sizeof(seraddr));

	listen(sfd, 5);

	fd_set rset, set;
	FD_ZERO(&set);
	FD_SET(sfd, &set);		

	int ret;	
	char buf[BUFSIZ];
	int maxfd = sfd;

	int txtfd = open("/home/ubuntu/algorithm/Socket/txt",	O_CREAT|O_TRUNC|O_RDWR, 0666);
	//dup2(txtfd,STDOUT_FILENO);//dup2 is useful.
	ftruncate(txtfd, BUFSIZ);

	while(1)
	{
		rset = set;
		ret = select(maxfd+1, &rset, NULL, NULL, NULL);
		printf("ret: %d\n",ret);
		if(ret < 0)
		perror("select:");
		else if(ret == 0)
		continue;		

		if(FD_ISSET(sfd, &rset))
		{
			struct sockaddr_in cliaddr;
			memset(&cliaddr, 0, sizeof(cliaddr));
			socklen_t cliaddrlen = sizeof(cliaddr);

			int cfd = accept(sfd, (struct sockaddr*)&cliaddr, &cliaddrlen);
			FD_SET(cfd, &set);

			if(maxfd < cfd)	
			maxfd = cfd;

			if(ret == 1)
			continue;	
		}

		for(int i = sfd+1; i <= maxfd; i++)
		{
			if(FD_ISSET(i, &rset))
			{
				ret = read(i, buf, sizeof(buf));
				if(ret == 0)
				{
					FD_CLR(i, &set);
					close(i);
					continue;			
				}
				write(txtfd, buf, ret);
				write(i, buf, ret);

				if(buf[0] == '?')
				{
					ret = read(txtfd, buf, sizeof(buf));
					write(STDOUT_FILENO, buf, ret);//cannot read from txtfd.How can I do?
					printf("txt: %d\n",ret);
					continue;
				}

				for(int i = 0; i < ret; i++)
				{	
					printf("%c",buf[i]);
					if(buf[i] == '\n')
					continue;
					fprintf(stdout, "%c", buf[i]);
				}
			}
		}	
	}
	return 0;
}
